﻿using mozhi.smarterp.Finance.Finances.Repository;
using mozhi.smarterp.Finance.Finances.Services;
using mozhi.smarterp.Finance.Querys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.ObjectMapping;

namespace mozhi.smarterp.Finance.Finances
{
    public class EndPeriodProcessResultAppService : FinanceAppService, IEndPeriodProcessResultAppService
    {
        private IEndPeriodProcessResultRepository _repository;
        private IEndPeriodProcessItemRepository _itemRepository;
        private EndPeriodProcessManager _manager;

        public EndPeriodProcessResultAppService(IEndPeriodProcessResultRepository repository, IEndPeriodProcessItemRepository itemRepository,
            EndPeriodProcessManager manager)
        {
            _repository = repository;
            _itemRepository = itemRepository;
            _manager = manager;
        }

        public async Task<EndPeriodProcessResultDto> MeasureAsync(EndPeriodProcessResultCreateDto item)
        {
            var processItem = await _itemRepository.FindAsync(item.ItemId , true);

            if (processItem == null)
                throw new UserFriendlyException($"期末处理项：{item.ItemId}不存在", "100000");

            if (processItem.Settings == null)
                throw new UserFriendlyException($"期末处理项：{processItem.Name}未设置科目信息", "100000");

            var result = await _manager.GetProcessResultAsync(processItem, item.Period);

            var matchId = (await _repository.FindAsync(new EndPeriodProcessResultQuery() { ItemId = processItem.Id  , Period = item.Period , IncludeDetail=true})).FirstOrDefault()?.Id;

            if(matchId == null)
                result = await _repository.InsertAsync(result);
            else
            {
                var matchResult = await _repository.GetAsync(matchId.Value, true);

                matchResult.Change(result.NeedProcess, result.Finshed, result.JournalId, result.MeasureValue, result.NeedEdit);
                matchResult.Items.Clear();

                result.Items.ForEach(item =>
                {
                    matchResult.AddItem(item);
                });

                result = await _repository.UpdateAsync(matchResult);
            }

            return ObjectMapper.Map<EndPeriodProcessResult, EndPeriodProcessResultDto>(result);
        }


        public async Task<JournalDto> GenerateJournalAsync(EndPeriodProcessResultCreateDto item)
        {
            var processItem = await _itemRepository.FindAsync(item.ItemId, true);

            if (processItem == null)
                throw new UserFriendlyException($"期末处理项：{item.ItemId}不存在", "100000");

            if (processItem.Settings == null)
                throw new UserFriendlyException($"期末处理项：{processItem.Name}未设置科目信息", "100000");

            var result = await _manager.GenerateJournal(processItem, item.Period);

            return ObjectMapper.Map<Journal, JournalDto>(result);
        }

        public async Task<List<EndPeriodProcessResultDto>> FindAsync(EndPeriodProcessResultQuery query)
        {
            var result = await _repository.FindAsync(query);

            return ObjectMapper.Map<List<EndPeriodProcessResult>, List<EndPeriodProcessResultDto>>(result);
        }

        public async Task<EndPeriodProcessResultDto> GetAsync(Guid itemId)
        {
            var result = await _repository.FindAsync(itemId, true);

            return ObjectMapper.Map<EndPeriodProcessResult, EndPeriodProcessResultDto>(result);
        }

        public Task<EndPeriodProcessResultDto> UpdateAsync(EndPeriodProcessResultUpdateDto item)
        {
            throw new NotImplementedException();
        }

     
    }
}
